package org.dxy.trigger.http.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dxy.api.dto.param.CreateParamDefinitionRequest;
import org.dxy.api.dto.param.UpdateParamDefinitionRequest;
import org.dxy.api.response.R;
import org.dxy.infrastructure.persistent.db.mybatispuls.po.ParamDefinitionPo;
import org.dxy.infrastructure.persistent.db.mybatispuls.service.ParamDefinitionService;
import org.dxy.trigger.http.service.ParamDefinitionApplicationService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @description: 参数定义应用服务实现类
 * @author: dxy
 * @createTime: 2025/1/21
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ParamDefinitionApplicationServiceImpl implements ParamDefinitionApplicationService {

    private final ParamDefinitionService paramDefinitionService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Long> create(CreateParamDefinitionRequest dto) {
        log.info("创建参数定义 - 参数编码: {}, 参数名称: {}", dto.getCode(), dto.getName());

        // 检查参数编码是否已存在
        int count = paramDefinitionService.checkCodeExists(dto.getCode(), null);
        if (count > 0) {
            log.warn("参数编码已存在 - 编码: {}", dto.getCode());
            return R.fail("参数编码已存在: " + dto.getCode());
        }

        // 创建参数定义实体
        ParamDefinitionPo entity = new ParamDefinitionPo();
        BeanUtils.copyProperties(dto, entity);

        // 保存到数据库
        boolean result = paramDefinitionService.save(entity);
        if (result) {
            log.info("参数定义创建成功 - ID: {}, 编码: {}", entity.getId(), dto.getCode());
            return R.ok(entity.getId());
        } else {
            log.error("参数定义创建失败 - 编码: {}", dto.getCode());
            return R.fail("参数定义创建失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> update(UpdateParamDefinitionRequest dto) {
        log.info("更新参数定义 - ID: {}, 参数编码: {}", dto.getId(), dto.getCode());

        // 检查参数定义是否存在
        ParamDefinitionPo existEntity = paramDefinitionService.getById(dto.getId());
        if (existEntity == null) {
            log.warn("参数定义不存在 - ID: {}", dto.getId());
            return R.fail("参数定义不存在");
        }

        // 检查参数编码是否已被其他记录使用
        int count = paramDefinitionService.checkCodeExists(dto.getCode(), dto.getId());
        if (count > 0) {
            log.warn("参数编码已被其他记录使用 - 编码: {}", dto.getCode());
            return R.fail("参数编码已被其他记录使用: " + dto.getCode());
        }

        // 更新参数定义实体
        ParamDefinitionPo entity = new ParamDefinitionPo();
        BeanUtils.copyProperties(dto, entity);

        // 更新到数据库
        boolean result = paramDefinitionService.updateById(entity);
        if (result) {
            log.info("参数定义更新成功 - ID: {}", dto.getId());
            return R.ok();
        } else {
            log.error("参数定义更新失败 - ID: {}", dto.getId());
            return R.fail("参数定义更新失败");
        }
    }

    @Override
    public R<Page<ParamDefinitionPo>> list(Page<ParamDefinitionPo> page, ParamDefinitionPo query) {
        log.info("分页查询参数定义列表 - 页码: {}, 每页大小: {}", page.getCurrent(), page.getSize());

        try {
            Page<ParamDefinitionPo> result = paramDefinitionService.selectPageList(page, query);
            log.info("参数定义列表查询成功 - 总数: {}", result.getTotal());
            return R.ok(result);
        } catch (Exception e) {
            log.error("参数定义列表查询失败", e);
            return R.fail("参数定义列表查询失败: " + e.getMessage());
        }
    }

    @Override
    public R<ParamDefinitionPo> getById(Long id) {
        log.info("查询参数定义详情 - ID: {}", id);

        try {
            ParamDefinitionPo entity = paramDefinitionService.getById(id);
            if (entity != null) {
                log.info("参数定义详情查询成功 - ID: {}, 编码: {}", id, entity.getCode());
                return R.ok(entity);
            } else {
                log.warn("参数定义不存在 - ID: {}", id);
                return R.fail("参数定义不存在");
            }
        } catch (Exception e) {
            log.error("参数定义详情查询失败 - ID: {}", id, e);
            return R.fail("参数定义详情查询失败: " + e.getMessage());
        }
    }

    @Override
    public R<ParamDefinitionPo> getByCode(String code) {
        log.info("根据参数编码查询参数定义 - 编码: {}", code);

        try {
            ParamDefinitionPo entity = paramDefinitionService.selectByCode(code);
            if (entity != null) {
                log.info("参数定义查询成功 - 编码: {}, ID: {}", code, entity.getId());
                return R.ok(entity);
            } else {
                log.warn("参数定义不存在 - 编码: {}", code);
                return R.fail("参数定义不存在");
            }
        } catch (Exception e) {
            log.error("参数定义查询失败 - 编码: {}", code, e);
            return R.fail("参数定义查询失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<ParamDefinitionPo>> getAll() {
        log.info("获取所有参数定义");

        try {
            LambdaQueryWrapper<ParamDefinitionPo> wrapper = new LambdaQueryWrapper<>();
            wrapper.orderByAsc(ParamDefinitionPo::getCode);
            List<ParamDefinitionPo> list = paramDefinitionService.list(wrapper);
            log.info("获取所有参数定义成功 - 数量: {}", list.size());
            return R.ok(list);
        } catch (Exception e) {
            log.error("获取所有参数定义失败", e);
            return R.fail("获取所有参数定义失败: " + e.getMessage());
        }
    }

    @Override
    public R<List<ParamDefinitionPo>> getByInputType(String inputType) {
        log.info("根据输入类型查询参数定义 - 输入类型: {}", inputType);

        try {
            List<ParamDefinitionPo> list = paramDefinitionService.selectByInputType(inputType);
            log.info("根据输入类型查询参数定义成功 - 输入类型: {}, 数量: {}", inputType, list.size());
            return R.ok(list);
        } catch (Exception e) {
            log.error("根据输入类型查询参数定义失败 - 输入类型: {}", inputType, e);
            return R.fail("根据输入类型查询参数定义失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> delete(Long id) {
        log.info("删除参数定义 - ID: {}", id);

        // 检查参数定义是否存在
        ParamDefinitionPo entity = paramDefinitionService.getById(id);
        if (entity == null) {
            log.warn("参数定义不存在 - ID: {}", id);
            return R.fail("参数定义不存在");
        }

        // 检查参数是否被工序参数配置引用
        int usageCount = paramDefinitionService.checkParamUsage(id);
        if (usageCount > 0) {
            log.warn("参数定义被工序参数配置引用，无法删除 - ID: {}, 引用数量: {}", id, usageCount);
            return R.fail("参数定义被工序参数配置引用，无法删除");
        }

        // 删除参数定义
        boolean result = paramDefinitionService.removeById(id);
        if (result) {
            log.info("参数定义删除成功 - ID: {}", id);
            return R.ok();
        } else {
            log.error("参数定义删除失败 - ID: {}", id);
            return R.fail("参数定义删除失败");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<Void> batchDelete(List<Long> ids) {
        log.info("批量删除参数定义 - ID列表: {}", ids);

        // 检查每个参数是否被工序参数配置引用
        for (Long id : ids) {
            int usageCount = paramDefinitionService.checkParamUsage(id);
            if (usageCount > 0) {
                log.warn("参数定义被工序参数配置引用，无法删除 - ID: {}, 引用数量: {}", id, usageCount);
                return R.fail("参数定义ID " + id + " 被工序参数配置引用，无法删除");
            }
        }

        // 批量删除参数定义
        int result = paramDefinitionService.batchDeleteByIds(ids);
        if (result > 0) {
            log.info("批量删除参数定义成功 - 删除数量: {}", result);
            return R.ok();
        } else {
            log.error("批量删除参数定义失败 - ID列表: {}", ids);
            return R.fail("批量删除参数定义失败");
        }
    }
}